package com.wlq.demo.uitls;

import com.wlq.demo.entity.SchemeFileCatalog;
import org.apache.tools.zip.ZipEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.tools.zip.ZipOutputStream;

/**
 * @author csb
 * @description: TODO
 * @date 2023/12/14 10:24
 */
public class ZipUtil {

    private static Logger logger = LoggerFactory.getLogger(ZipUtil.class);
    // 目录标识判断符
    private static final String PATCH = "/";
    // 基目录
    private static final String BASE_DIR = "/b/";
    // 缓冲区大小
    private static final int BUFFER = 2048;
    // 字符集
    private static final String CHAR_SET = "UTF-8";

//    public static void test() {
//        //获取文件和目录集合
//        List<SchemeFileCatalog> list = new ArrayList<SchemeFileCatalog>();
//
//        if (list != null && list.size() > 0) {
//            String zipName = "方案附件信息.zip";
//            response.setContentType("application/octet-stream");// 指明response的返回对象是文件流
//            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName, "UTF-8"));
//            // ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(new File("D:/a/a.zip")));
//            ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
//            zipOutputStream.setMethod(ZipOutputStream.DEFLATED);//设置压缩方法
//
//            //声明一个存放文件路径的集合
//            List<File> files = new ArrayList<File>();
//            //文件夹名
//            List<String> totalFolderList = new ArrayList<String>();
//
//            for (int i = 0; i < list.size(); i++) {
//                //当前目录名
//                String superFolderName = list.get(i).getName();
//                //当前目录下的文件
//                List<SchemeFileCatalog> child = list.get(i).getChild();
//                for (int j = 0; j < child.size(); j++) {
//                    //文件名称
//                    String fileName = child.get(j).getName();
//                    //获取文件在本地的地址
//                    String filePath = FileUtils.appendFilePath(basedir, children.get(j).getPath().substring(8));
//                    //构建二级文件夹名
//                    totalFolderList.add(superFolderName + "\\" + fileName + "\\");
//                    files.add(new File(filePath));
//                }
//            }
//            if (CollectionUtils.isEmpty(files) == false) {
//                for (int i = 0, size = totalFolderList.size(); i < size; i++) {
//                    //调用工具类方法
//                    ZipUtil.compress(files.get(i), zipOutputStream, totalFolderList.get(i));
//                }
//                //强行把Buffer的 内容写到客户端浏览器
//                response.flushBuffer();
//                // 冲刷输出流
//                zipOutputStream.flush();
//                //            zipOutputStream.finish();
//                // 关闭输出流
//                zipOutputStream.close();
//            }
//        }
//    }


    /**
     *
     * @param srcFile   file对象
     * @param zipOutputStream
     * @param basePath  压缩文件路径
     * @throws Exception
     */
    public static void compress(File srcFile, ZipOutputStream zipOutputStream, String basePath) throws Exception {
        if (srcFile.isDirectory()) {
            compressDir(srcFile, zipOutputStream, basePath);
        } else {
            compressFile(srcFile, zipOutputStream, basePath);
        }
    }


    private static void compressDir(File dir, ZipOutputStream zipOutputStream, String basePath) throws Exception {
        try {
            // 获取文件列表
            File[] files = dir.listFiles();

            if (files.length < 1) {
                ZipEntry zipEntry = new ZipEntry(dir.getParent().substring(3,dir.getParent().length()) + PATCH);

                zipOutputStream.putNextEntry(zipEntry);
                zipOutputStream.closeEntry();
            }

            for (int i = 0,size = files.length; i < size; i++) {
                compress(files[i], zipOutputStream, basePath + dir.getName() + PATCH);
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

    private static void compressFile(File file, ZipOutputStream zipOutputStream, String dir) throws Exception {
        try {
            // 压缩文件
            ZipEntry zipEntry = new ZipEntry(file.getParent().substring(3,file.getParent().length()) + PATCH + file.getName());
            zipOutputStream.putNextEntry(zipEntry);

            // 读取文件
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

            int count = 0;
            byte data[] = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                zipOutputStream.write(data, 0, count);
            }
            bis.close();
            zipOutputStream.closeEntry();
        } catch (Exception e) {
            throw new Exception(e.getMessage(),e);
        }
    }

    private static void compressFile2(InputStream inputStream, ZipOutputStream zipOutputStream, String dir) throws Exception {
        try {
            // 压缩文件
            ZipEntry zipEntry = new ZipEntry(dir);
            zipOutputStream.putNextEntry(zipEntry);

            // 读取文件
            BufferedInputStream bis = new BufferedInputStream(inputStream);

            int count = 0;
            byte data[] = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                zipOutputStream.write(data, 0, count);
            }
            bis.close();
            zipOutputStream.closeEntry();
        } catch (Exception e) {
            throw new Exception(e.getMessage(),e);
        }
    }


    public static void main(String[] args) {
        try {
            ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(new File("D:/test/aa/a.zip")));
            zipOutputStream.setEncoding(CHAR_SET);

//            List<File> files = new ArrayList<File>();
//            files.add(new File("D:\\test\\aa\\b\\1.doc"));
//            files.add(new File("D:\\test\\aa\\11.docx"));
//
//            if (CollectionUtils.isEmpty(files) == false) {
//                for (int i = 0,size = files.size(); i < size; i++) {
//                    compress(files.get(i), zipOutputStream, BASE_DIR);
//                }
//            }

            String fileName = "D:\\test\\aa\\b\\1.doc";
            String fileName2 = "D:\\test\\aa\\11.docx";
            InputStream fileInputStream = new FileInputStream(fileName);
            InputStream fileInputStream2 = new FileInputStream(fileName2);

            Map<String, InputStream> map = new HashMap<>();

            map.put(fileName,fileInputStream);
            map.put(fileName2,fileInputStream2);

            map.forEach((k,v) -> {
                try {
                    compressFile2(v, zipOutputStream, k.substring(3,k.length()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });




            // 冲刷输出流
            zipOutputStream.flush();
            // 关闭输出流
            zipOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
